﻿using CommonTool;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Drawing;
using System.IO.Ports;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace AutoMachine
{
    public partial class Frm_SerialPort : Form
    {
        #region 窗体实例化
        /// <summary>
        /// 窗体对象实例化
        /// </summary>
        private static Frm_SerialPort _instance;
        internal static Frm_SerialPort Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new Frm_SerialPort();
                return _instance;
            }
        }
        #endregion

        public Frm_SerialPort()
        {
            InitializeComponent();
        }


        /// <summary>
        /// 通讯用串口类
        /// </summary>
        public SerialPort serialPort = new SerialPort();
        /// <summary>
        /// 串口号
        /// </summary>
        private string portName = "COM11";
        /// <summary>
        /// 波特率
        /// </summary>
        private int baudRate = 921600;
        /// <summary>
        /// 数据位
        /// </summary>
        private int dataBit = 8;
        /// <summary>
        /// 停止位
        /// </summary>
        private StopBits stopBit = (StopBits)Enum.Parse(typeof(StopBits), "One");
        /// <summary>
        /// 奇偶效验位
        /// </summary>
        private Parity parity = (Parity)Enum.Parse(typeof(Parity), "Odd");


        /// <summary>
        /// 打开串口
        /// </summary>
        public void OpenPort()
        {
            try
            {
                if (!serialPort.IsOpen)
                {
                    serialPort.NewLine = "\r\n";
                    serialPort.RtsEnable = false;
                    serialPort.PortName = portName;//端口号
                    serialPort.BaudRate = baudRate;//波特率
                    serialPort.DataBits = dataBit;//数据位
                    serialPort.StopBits = StopBits.One;//停止位
                    serialPort.Parity = Parity.None;//奇偶校验位
                    serialPort.Open();//打开端口
                    serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived);
                    lbl_statu.Text = "已打开";
                    ReadData();
                    //Consumer();
                    lbl_statu.ForeColor = Color.Green;

                }
            }
            catch (Exception ex)
            {
                lbl_statu.Text = "未打开";
                lbl_statu.ForeColor = Color.Red;
                LogView.GetInstance().ShowLogSave(LogView.LogType.Error, ex.Message);//保存Log
                MessageBox.Show(ex.Message);

            }
        }


        /// <summary>
        /// 关闭串口
        /// </summary>
        public void ClosePort()
        {
            try
            {
                if (serialPort.IsOpen)//打开状态
                {
                    serialPort.Close();//关闭端口
                    lbl_statu.Text = "未打开";
                    lbl_statu.ForeColor = Color.Red;
                }
            }
            catch (Exception ex)
            {
                LogView.GetInstance().ShowLogSave(LogView.LogType.Error, ex.Message);//保存Log
                MessageBox.Show(ex.Message);
            }


        }

        /// <summary>
        /// 为整数
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool IsInt(string value)
        {
            return Regex.IsMatch(value, "^-?\\d+$");
        }

        //窗口打开
        private void FrmSerialPort_Load(object sender, EventArgs e)
        {
            try
            {
                //端口名字
                cbx_portName.Items.Clear();
                cbx_portName.Items.AddRange(SerialPort.GetPortNames());//获取当前计算机上可用的端口列表
                //奇偶校验位
                cbx_parityBit.Items.Clear();
                foreach (var item in Enum.GetValues(typeof(Parity)))
                {
                    cbx_parityBit.Items.Add(item.ToString());

                }
                //停止位
                cbx_stopBit.Items.Clear();
                foreach (var item in Enum.GetValues(typeof(StopBits)))
                {
                    cbx_stopBit.Items.Add(item.ToString());
                }
                if (cbx_portName.Items.Count > 0)
                {
                    cbx_portName.SelectedIndex = 0;
                }
                if (cbx_parityBit.Items.Count > 0)
                    cbx_parityBit.SelectedIndex = 1;
                if (cbx_stopBit.Items.Count > 1)
                    cbx_stopBit.SelectedIndex = 1;
            }
            catch (Exception ex)
            {
                LogView.GetInstance().ShowLogSave(LogView.LogType.Error, ex.Message);//保存Log
                MessageBox.Show(ex.Message);
            }
        }

        //端口号
        private void cbx_portName_SelectedIndexChanged(object sender, EventArgs e)
        {
            portName = cbx_portName.Text.Trim();
        }

        //波特率
        private void cbx_baudRate_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (IsInt(cbx_baudRate.Text.Trim()))
            {
                cbx_baudRate.Text = "921600";
                return;
            }
            baudRate = Convert.ToInt32(cbx_baudRate.Text.Trim());
        }

        //数据位
        private void cbx_dataBit_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (IsInt(cbx_dataBit.Text.Trim()))
            {
                cbx_dataBit.Text = "8";
                return;
            }
            dataBit = Convert.ToInt32(cbx_dataBit.Text.Trim());
        }

        //停止位
        private void cbx_stopBit_SelectedIndexChanged(object sender, EventArgs e)
        {
            stopBit = (StopBits)Enum.Parse(typeof(StopBits), cbx_stopBit.Text);
        }

        //奇偶校验位
        private void cbx_parityBit_SelectedIndexChanged(object sender, EventArgs e)
        {
            parity = (Parity)Enum.Parse(typeof(Parity), cbx_parityBit.Text);
        }

        //打开串口
        private void btn_openPort_Click(object sender, EventArgs e)
        {
            OpenPort();
        }

        //关闭串口
        private void btn_closePort_Click(object sender, EventArgs e)
        {
            ClosePort();
        }

        //清空
        private void lnk_clear_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            tbx_output.Clear();
        }

        //发送按钮
        private void btn_send_Click(object sender, EventArgs e)
        {
            try
            {
                if (!serialPort.IsOpen)
                {
                    MessageBox.Show("端口未打开");
                    return;
                }
                if (tbx_sendMsg.Text.Trim() == string.Empty)//没有字符串
                {
                    MessageBox.Show("不能发送空字符串");
                    return;
                }
                serialPort.ReadExisting();

                Cf_CRC16(strToToHexByte(tbx_sendMsg.Text.Trim()));
                serialPort.WriteLine(tbx_sendMsg.Text.Trim() + Cf_CRC16(strToToHexByte(tbx_sendMsg.Text.Trim())).ToString());//发送内容
                tbx_output.Text += DateTime.Now.ToString("HH:mm:ss") + "->:  " + tbx_sendMsg.Text.Trim() + Environment.NewLine;
            }
            catch (Exception ex)
            {
                LogView.GetInstance().ShowLogSave(LogView.LogType.Error, ex.Message);//保存Log
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// string  转byte
        /// </summary>
        /// <param name="hexString"></param>
        /// <returns></returns>
        public byte[] strToToHexByte(string hexString)
        {
            hexString = hexString.Replace(" ", "");
            if ((hexString.Length % 2) != 0)
                hexString += " ";
            byte[] returnBytes = new byte[hexString.Length / 2];
            for (int i = 0; i < returnBytes.Length; i++)
                returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
            return returnBytes;
        }

        void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                if (!serialPort.IsOpen)
                {
                    MessageBox.Show("串口未打开");
                    return;
                }
                //string receiveStr = serialPort.ReadExisting();//收到的内容
                //Byte[] BYTE = Encoding.ASCII.GetBytes(receiveStr);

                //if (receiveStr != "")
                //{
                //    tbx_output.Text += DateTime.Now.ToString("HH:mm:ss") + "<-:  " + receiveStr + Environment.NewLine;
                //    textBox1.Text = receiveStr;
                //}
                ReadData();
            }
            catch (Exception ex)
            {
                LogView.GetInstance().ShowLogSave(LogView.LogType.Error, ex.Message);//保存Log
                MessageBox.Show(ex.Message);
            }
        }

        public BlockingCollection<float> queue = new BlockingCollection<float>();
        //public Queue<float> queue = new Queue<float>();
        public Queue<float> queue1 = new Queue<float>();
        public Queue<float> queue2 = new Queue<float>();
        public Queue<float> queue3 = new Queue<float>();
        public Queue<float> queue4 = new Queue<float>();
        public Queue<float> queue5 = new Queue<float>();

        private void ReadData()
        {
            byte[] data = new byte[64];
            if (serialPort.BytesToRead > 64)
            {
                //Console.WriteLine($"queue长度：{serialPort.BytesToRead}");
                serialPort.Read(data, 0, data.Length);
                //if (GlobalVar.NeedTest)
                //{
                if (true)
                {
                    //queue.Add(((rtn1 + rtn2 + rtn3 + rtn4 + rtn5) / 5).ToString("F4"));
                    DoWork(data);
                    //queue.Enqueue(BitConverter.ToSingle(subdata1, 0));
                }
                else
                {
                    DoWorkTest(data);
                }

                //    queue.Enqueue(data);
                //}              
            }
        }

        private void DoWork(byte[] data)
        {
            for (int i = 0; i < data.Length - 3; i++)
            {
                if (data[0 + i] == 0x01 && data[1 + i] == 0x03 && data[2 + i] == 0x3c)
                {
                    if (i != 0)
                    {
                        byte[] datas = new byte[64 - i];
                        serialPort.Read(datas, 0, datas.Length);
                        break;
                    }
                    // 截取x轴对应的数据
                    byte[] subdata1 = new byte[4] { data[3], data[4], data[5], data[6] };
                    //byte[] subdata2 = new byte[4] { data[12 + 3], data[13 + 3], data[14 + 3], data[15 + 3] };
                    //byte[] subdata3 = new byte[4] { data[24 + 3], data[25 + 3], data[26 + 3], data[27 + 3] };
                    //byte[] subdata4 = new byte[4] { data[36 + 3], data[37 + 3], data[38 + 3], data[39 + 3] };
                    //byte[] subdata5 = new byte[4] { data[48 + 3], data[49 + 3], data[50 + 3], data[51 + 3] };
                    float rtn1 = BitConverter.ToSingle(subdata1, 0);
                    //float rtn2 = BitConverter.ToSingle(subdata2, 0);
                    //float rtn3 = BitConverter.ToSingle(subdata3, 0);
                    //float rtn4 = BitConverter.ToSingle(subdata4, 0);
                    //float rtn5 = BitConverter.ToSingle(subdata5, 0);

                    break;
                }
            }


        }
        private void DoWorkTest(byte[] data)
        {

            if (data[0] == 0x01 && data[1] == 0x03 && data[2] == 0x3c)
            {

                // 截取x轴对应的数据
                byte[] subdata1 = new byte[4] { data[3], data[4], data[5], data[6] };
                byte[] subdata2 = new byte[4] { data[12 + 3], data[13 + 3], data[14 + 3], data[15 + 3] };
                byte[] subdata3 = new byte[4] { data[24 + 3], data[25 + 3], data[26 + 3], data[27 + 3] };
                byte[] subdata4 = new byte[4] { data[36 + 3], data[37 + 3], data[38 + 3], data[39 + 3] };
                byte[] subdata5 = new byte[4] { data[48 + 3], data[49 + 3], data[50 + 3], data[51 + 3] };
                float rtn1 = BitConverter.ToSingle(subdata1, 0);
                float rtn2 = BitConverter.ToSingle(subdata2, 0);
                float rtn3 = BitConverter.ToSingle(subdata3, 0);
                float rtn4 = BitConverter.ToSingle(subdata4, 0);
                float rtn5 = BitConverter.ToSingle(subdata5, 0);

                queue.Add((rtn1 + rtn2 + rtn3 + rtn4 + rtn5) / 5);
                //queue.Add(rtn1);
                //queue.Add(rtn2);
                //queue.Add(rtn3);
                //queue.Add(rtn4);
                //queue.Add(rtn5);
                //queue.Enqueue(BitConverter.ToSingle(subdata1, 0));



            }


        }
        private void Consumer()
        {
            Task.Run(() => {
                while (true)
                {
                    //float data = queue.Take();
                    //Console.WriteLine($"queue长度：{queue.Count}");
                    //Console.WriteLine($"获取数据长度：{data.Length}");
                }
            }
            );

        }
        private ushort Cf_CRC16(byte[] data)
        {
            ushort crc = 0xffff;
            int f;
            for (int i = 0; i < data.Length; i++)
            {
                crc ^= data[i];
            }
            for (int i = 0; i < 8; i++)
            {
                f = crc & 1;
                crc >>= 1;
                if (f == 1)
                {
                    crc ^= 0xa001; // 多项式
                }
            }
            return crc;
        }


    }
}